<template>
	<div :class="['p__main']">
		<div class="p__tools" v-if="controls">
			<div class="p__template">
				<label class="p__template-item">
					<div class="p__choose">
						<img src="./static/image.png" />
						<span>图片</span>
					</div>
					<input ref="file" type="file" id="file" multiple="multiple" accept="image/png,image/jpg,image/jpeg"
						@input="chooseImage" />
				</label>
				<div class="p__template-item" @click="addText">
					<div class="p__choose choose-text">
						<img src="./static/text.png" />
						<span>文字</span>
					</div>
				</div>
				<div class="p__template-item" @click="addCode">
					<div class="p__choose">
						<img src="./static/qrcode.png" />
						<span>二维码</span>
					</div>
				</div>
			</div>
			<div class="p__template">
				<div class="p__template-item" @click="save">
					<div class="p__choose">
						<img src="./static/save.png" />
						<span>保存</span>
					</div>
				</div>
				<div class="p__template-item" @click="download">
					<div class="p__choose">
						<img src="./static/download.png" />
						<span>下载</span>
					</div>
				</div>
			</div>
		</div>
		<div class="p__panel" :style="panelStyle" @click.self="blur">
			<div class="p__item" v-for="(item,index) in views" :style="boxStyle(item)"
				@mousedown.prevent="function(e){mousedown(e,item,index)}"
				@mousemove.prevent="function(e){mousemove(e,item)}" @mouseup.prevent="function(e){mouseup(e,item)}"
				@mouseleave.prevent="function(e){mouseup(e,item)}">
				<div class="p__delete" @click="remove(index)" v-if="curIndex===index"></div>
				<div class="p__acitve" v-if="curIndex===index"></div>
				<span v-if="item.type === 'text'" :style="item.style">{{item.content}}</span>
			</div>
		</div>
		<div class="p__option" v-if="curIndex > -1">
			<div class="p__delete" @click="remove(curIndex)"></div>
			<div class="p__form">
				<template v-if="['text','qrcode'].includes(curData.type)">
					<div class="p__form-item">
						<div class="p__form-item-label">内容</div>
						<div class="p__form-item-content">
							<textarea class="p__form-textarea" rows="2" placeholder="请输入内容"
								v-model="curData.content"></textarea>
						</div>
					</div>
				</template>
				<template v-if="curData.type === 'text'">
					<div class="p__form-item">
						<div class="p__form-item-label">字号</div>
						<div class="p__form-item-content">
							<input class="p__form-input" v-model="curData.style.fontSize"></input>
						</div>
					</div>
					<div class="p__form-item">
						<div class="p__form-item-label">字重</div>
						<div class="p__form-item-content">
							<radio v-model="curData.style.fontWeight" label="normal">默认</radio>
							<radio v-model="curData.style.fontWeight" label="bold">加粗</radio>
						</div>
					</div>
					<div class="p__form-item">
						<div class="p__form-item-label">颜色</div>
						<div class="p__form-item-content">
							<color-picker v-model="curData.style.color"></color-picker>
						</div>
					</div>
				</template>
				<template v-if="curData.type === 'image'">
					<div class="p__form-item">
						<div class="p__form-item-label">圆角</div>
						<div class="p__form-item-content">
							<input-number v-model.number="curData.pos.radius" :min="0"></input-number>
						</div>
					</div>
				</template>
				<div class="p__form-item">
					<div class="p__form-item-label">宽</div>
					<div class="p__form-item-content">
						<input-number v-model.number="curData.pos.w" :min="0"></input-number>
					</div>
				</div>
				<div class="p__form-item">
					<div class="p__form-item-label">高</div>
					<div class="p__form-item-content">
						<input-number v-model.number="curData.pos.h" :min="0"></input-number>
					</div>
				</div>
				<div class="p__form-item">
					<div class="p__form-item-label">x</div>
					<div class="p__form-item-content">
						<input-number v-model.number="curData.pos.x"></input-number>
					</div>
				</div>
				<div class="p__form-item">
					<div class="p__form-item-label">y</div>
					<div class="p__form-item-content">
						<input-number v-model.number="curData.pos.y"></input-number>
					</div>
				</div>
				<div class="p__form-item">
					<div class="p__form-item-label">z</div>
					<div class="p__form-item-content">
						<input-number v-model.number="curData.pos.z"></input-number>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
	import * as poster from './utils/poster.js'
	import inputNumber from './components/input-number/index.vue'
	import radio from './components/radio/index.vue'
	import colorPicker from './components/color-picker/index.vue'
	export default {
		name: 'el-poster',
		components:{inputNumber,radio,colorPicker},
		props: {
			controls: {
				type: Boolean,
				default: true
			},
			width: {
				type: Number,
				default: 400
			},
			height: {
				type: Number,
				default: 600
			},
			backgroundColor: {
				type: String,
				default: '#e0e0e0'
			}
		},
		data() {
			return {
				curIndex: -1,
				curData: {},
				viewWidth: 0,
				viewHeight: 0,
				views: []
			}
		},
		computed: {
			panelStyle() {
				return {
					width: this.viewWidth + 'px',
					height: this.viewHeight + 'px',
					backgroundColor: this.backgroundColor
				}
			}
		},
		created() {
			this.$nextTick(() => {
				this.viewWidth = this.width;
				this.viewHeight = this.height;
			})
		},
		watch: {
			width(val) {
				this.viewWidth = this.val;
			},
			height(val) {
				this.viewHeight = this.val;
			}
		},
		methods: {
			boxStyle(item) {
				let result = {
					width: item.pos.w + 'px',
					height: item.pos.h + 'px',
					top: item.pos.y + 'px',
					left: item.pos.x + 'px',
					borderRadius: item.pos.radius + 'px',
					zIndex: item.pos.z,
				}
				if (item.type === 'image') {
					result['backgroundImage'] = `url(${item.src})`;
					result['backgroundSize'] = '100% 100%';
				}
				if (item.type === 'qrcode') {
					result['backgroundImage'] = `url(${require('./static/qrcode_x.png')})`;
					result['backgroundSize'] = '100% 100%';
					result['backgroundColor'] = '#FFFFFF';
				}
				if (item.bgColor) {
					result['backgroundColor'] = item.bgColor;
				}
				return result
			},
			blur() {
				this.curIndex = -1;
				this.curData = {};
			},
			mousedown(e, item, index) {
				if (!this.controls) return;
				this.curIndex = index;
				this.curData = item;
				item.dragging = true;
			},
			mousemove(e, item) {
				if (!this.controls) return;
				if (item.dragging) {
					item.pos.x += e.movementX
					item.pos.y += e.movementY
				}
			},
			mouseup(e, item) {
				if (!this.controls) return;
				item.dragging = false;
			},
			remove(index) {
				this.views.splice(index, 1);
				this.curIndex = -1;
				this.curData = {};
			},
			async chooseImage(e) {
				let files = e.target.files;
				for (let file of files) {
					await this.addImage(file);
				}
				this.$refs.file.value = null;
			},
			addImage(file) {
				let _this = this;
				let reader = new FileReader();
				reader.onload = function(evt) {
					let base64 = evt.target.result;
					let img = new Image();
					img.src = base64;
					img.onload = function() {
						_this.views.push({
							dragging: false,
							type: 'image',
							src: base64,
							pos: {
								x: _this.viewWidth * 0.1,
								y: _this.viewHeight * 0.1,
								z: 0,
								w: img.width,
								h: img.height,
								radius: 0
							}
						})
						Promise.resolve()
					}
				}
				reader.readAsDataURL(file)
			},
			addText() {
				this.views.push({
					dragging: false,
					type: 'text',
					content: '请输入文字',
					style: {
						fontSize: '14px',
						color: '#5F5F5F',
						fontWeight: 'normal',
					},
					pos: {
						x: this.viewWidth * 0.1,
						y: this.viewHeight * 0.1,
						z: 0,
						w: 100,
						h: 20
					}
				})
				this.curIndex = this.views.length - 1;
				this.curData = this.views[this.curIndex];
			},
			addCode() {
				this.views.push({
					dragging: false,
					type: 'qrcode',
					content: '二维码内容',
					pos: {
						x: this.viewWidth * 0.1,
						y: this.viewHeight * 0.1,
						z: 0,
						w: 100,
						h: 100
					}
				})
				this.curIndex = this.views.length - 1;
				this.curData = this.views[this.curIndex];
			},
			save() {
				poster.makePoster({
					views: this.views,
					width: this.viewWidth,
					height: this.viewHeight,
					backgroundColor: this.backgroundColor
				}).then(res => {
					this.$emit('result', res);
				}).catch(err => {
					this.$emit('error', err);
				})
			},
			setOptions(options) {
				this.views = options.views;
				this.viewWidth = options.width;
				this.viewHeight = options.height;
			},
			makePoster(options) {
				try {
					this.setOptions(options);
					poster.makePoster(options).then(res => {
						this.$emit('result', res);
					}).catch(err => {
						this.$emit('error', err);
					})
				} catch (e) {
					this.$emit('error', e);
				}
			},
			download() {
				poster.makePoster({
					views: this.views,
					width: this.viewWidth,
					height: this.viewHeight,
					backgroundColor: this.backgroundColor
				}).then(res => {
					let aLink = document.createElement('a');
					let blob = this.base64ToBlob(res.base64);
					let evt = document.createEvent("HTMLEvents");
					evt.initEvent("click", true, true);
					aLink.download = '1.png';
					aLink.href = URL.createObjectURL(blob);
					aLink.click()
				})
			},
			base64ToBlob(code) {
				let parts = code.split(';base64,');
				let contentType = parts[0].split(':')[1];
				let raw = window.atob(parts[1]);
				let rawLength = raw.length;

				let uInt8Array = new Uint8Array(rawLength);

				for (let i = 0; i < rawLength; ++i) {
					uInt8Array[i] = raw.charCodeAt(i);
				}
				return new Blob([uInt8Array], {
					type: contentType
				});
			}
		}
	}
</script>

<style>
	.p__hide {
		display: none !important;
	}

	.p__main {
		position: relative;
		display: flex;
		justify-content: flex-start;
		align-items: flex-start;
		padding: 15px;
	}

	.p__panel {
		position: relative;
		overflow: hidden;
	}

	.p__item {
		position: absolute;
	}

	.p__acitve {
		width: 100%;
		height: 100%;
		position: absolute;
		box-shadow: 0 0 0 1px #ffffff;
		left: 0;
		top: 0;
	}

	.p__delete {
		width: 18px;
		height: 18px;
		position: absolute;
		top: -9px;
		right: -9px;
		background-image: url(static/delete.png);
		background-size: cover;
		background-color: #FFFFFF;
		border-radius: 50%;
		z-index: 99;
	}

	.p__option {
		position: relative;
		min-height: 100px;
		border: 1px solid #cecece;
		margin-left: 15px;
		border-radius: 4px;
		padding: 20px;
	}

	.p__opt-input {
		margin-bottom: 5px;
		width: 100%;
	}

	.p__template {
		padding: 5px;
		box-shadow: 0 0 12px #0000001a;
		margin-right: 15px;
		margin-bottom: 15px;
		border-radius: 4px;
	}

	.p__template-item {
		text-align: center;
		cursor: pointer;
	}

	.p__choose {
		margin: 0 auto;
		width: 50px;
		height: 50px;
		padding: 5px;
		margin-bottom: 15px;
	}

	input[id="file"] {
		display: none;
	}

	.p__choose img {
		width: 30px;
		height: 30px;
		margin: 0 auto;
	}

	.p__choose span {
		font-size: 12px;
		color: #8d8d8d;
	}

	.p__choose-text img {
		height: 25px;
	}

	.p__form {}
	
	.p__form::after{
		clear: both;
	}

	.p__form-item {
		margin-bottom: 15px !important;
	}

	.p__form-item::after {
		clear: both;
	}

	.p__form-item-label {
		width: 40px;
		line-height: 28px;
		text-align: right;
		vertical-align: middle;
		float: left;
		font-size: 14px;
		color: #606266;
		padding: 0 12px 0 0;
		box-sizing: border-box;
		font-weight: 700;
	}

	.p__form-item-content {
		margin-left: 40px;
		line-height: 28px;
		position: relative;
		font-size: 14px;
	}

	.p__form-item-content::after {
		clear: both;
	}

	.p__form-textarea {
		display: block;
		resize: vertical;
		padding: 5px 15px;
		line-height: 1.5;
		-webkit-box-sizing: border-box;
		box-sizing: border-box;
		width: 100%;
		font-size: inherit;
		color: #606266;
		background-color: #FFF;
		background-image: none;
		border: 1px solid #DCDFE6;
		border-radius: 4px;
		outline: none;
		-webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
		transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
	}

	.p__form-input {
		background-color: #FFF;
		background-image: none;
		border-radius: 4px;
		border: 1px solid #DCDFE6;
		box-sizing: border-box;
		color: #606266;
		display: inline-block;
		font-size: inherit;
		height: 40px;
		line-height: 40px;
		outline: 0;
		padding: 0 15px;
		transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
		width: 100%;
		font-size: 12px;
		height: 28px;
		line-height: 28px;
	}
	
	.p__form-input:focus,.p__form-textarea:focus{
		border-color: #409EFF;
	}
</style>
